package client;

import java.util.ArrayList;

import javax.swing.JFrame;

import GUI.Activity_Report;
import GUI.Book_opp;
import GUI.Client_GUI;
import GUI.Home;
import GUI.LateReturnReport;
import GUI.Late_report_result;
import GUI.Loan_Report;
import GUI.Manage_Stock;
import GUI.NotifyDialog;
import GUI.ResultDisplay;
import GUI.Return_Book;
import GUI.SearchBook;
import GUI.SearchLoan;
import GUI.SearchMember;
import GUI.SearchOrder;
import GUI.pdfView;
import logic.Member;
import logic.Message;
import logic.SystemMesseges;
import ocsf.client.ObservableClient;

public class OBL_Client extends ObservableClient{
	 
	public final static int MEMBER = 1000;
	public final static int LIBRARIAN = 100;
	public final static int MANAGER = 1;
	
	private Client_GUI client;
	
	private String UID;
	private String userName;
	public int Privelege;
	
	public ArrayList<SystemMesseges> privateMessages;
	public ArrayList<SystemMesseges> publicMessages;

	public OBL_Client(String host, int port,Client_GUI gui) {
		super(host, port);
		this.client = gui;
	}

	/**
	 * This function handles a message from server.
	 * Overridden from ObservableClient
	 * @param msg - the Message object
	 */
	@Override
	protected void handleMessageFromServer(Object msg) {
		
		Message received = (Message)msg;
		ArrayList<String> index = received.GetMessageIndexes();
		ArrayList<Object> data = received.GetMessageData();
		
		
		
		switch(received.GetAction()){ //handle all kinds of messages from server
		
		case Message.LOGIN_RESPONSE:{
			int priv = (Integer)data.get(0);
			this.Privelege = priv;
			this.userName = (String)data.get(1);
			client.setTopFrameTitle("Hello " + this.userName + "!"); //will be removed eventually

			switch(priv){
			case Member.MEMBER_PRIVILIGE:{}
			case Member.LIBRARIAN_PRIVILIGE:{}
			case Member.MANAGER_PRIVILIGE:{
				
				this.publicMessages = null;
				this.publicMessages = (ArrayList<SystemMesseges>)data.get(2);
				this.privateMessages = null;
				this.privateMessages = (ArrayList<SystemMesseges>)data.get(3);
				client.GetMessages(privateMessages);
				
				client.labelMeesege.setVisible(true);
				client.msgNum.setVisible(true);
				client.RepaintMenu(priv);
				client.btnLogoff.setVisible(true);
				//client.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
				break;
			}
			
			case Member.SYSTEM_USER_PRIVILIGE:{
				this.Privelege = Member.SYSTEM_USER_PRIVILIGE;
				this.publicMessages = (ArrayList<SystemMesseges>)data.get(2);
				this.privateMessages = null;
				client.RepaintMenu(priv);
				client.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				break;
			}
			
			case (-1):{		//login error
				NotifyDialog dlg = new NotifyDialog(client, (String)data.get(1));
				break;
			}
			}

			break;
		}
		
		case Message.SEARCH_BOOK_RESPONSE:{
			
			int selector = (Integer)received.GetMessageData().get(2);
			switch(selector){
			
			
			case SearchBook.SEARCH:{
				client.safeToClear = true;
				ResultDisplay topaint = new ResultDisplay(client, received,null);
				client.RepaintMain(topaint);
				break;
			}
			
			case SearchBook.SEARCH_FOR_DELETE:{}
			case SearchBook.SEARCH_FOR_UPDATE:{
				client.safeToClear = true;
				Manage_Stock next = (Manage_Stock)((SearchBook)client.currentMain).returnPanel;
				ResultDisplay topaint = new ResultDisplay(client, received,next);
				client.RepaintMain(topaint);
				break;

			}
			
			case SearchBook.SEARCH_FOR_CREATE_ORDER:{}
			case SearchBook.SEARCH_FOR_CREATE_LOAN:{
				client.safeToClear = true;
				Book_opp next = (Book_opp)((SearchBook)client.currentMain).returnPanel;
				ResultDisplay topaint = new ResultDisplay(client, received,next);
				client.RepaintMain(topaint);
				break;
			}
			
			case SearchBook.SEARCH_FOR_SEARCH_LOAN:{
				client.safeToClear = true;
				SearchLoan next = (SearchLoan)((SearchBook)client.currentMain).returnPanel;
				ResultDisplay topaint = new ResultDisplay(client, received, next);
				client.RepaintMain(topaint);
				break;
			}
			
			case SearchBook.SEARCH_FOR_SEARCH_ORDER:{
				client.safeToClear = true;
				SearchOrder next = (SearchOrder)((SearchBook)client.currentMain).returnPanel;
				ResultDisplay topaint = new ResultDisplay(client, received, next);
				client.RepaintMain(topaint);
				break;
			}
			
			case SearchBook.SEARCH_FOR_LATE_RETURN:{
				client.safeToClear = true;
				LateReturnReport next = (LateReturnReport)((SearchBook)client.currentMain).returnPanel;
				ResultDisplay topaint = new ResultDisplay(client, received, next);
				client.RepaintMain(topaint);
				break;
			}
			
			}

			
			break;
		}
		
		case Message.SEARCH_ORDER_RESPONSE:{
			client.safeToClear = true;
			
			ResultDisplay topaint = new ResultDisplay(client, received,null);
			client.RepaintMain(topaint);
			break;
		}
		
		case Message.SEARCH_LOAN_RESPONSE:{
			int selector = (Integer)received.GetMessageData().get(2);
			
			switch(selector){
			case SearchLoan.SEARCH_LOAN:{
				client.safeToClear = true;
				
				ResultDisplay topaint = new ResultDisplay(client, received,null);
				client.RepaintMain(topaint);
				break;
			}
			
			case SearchLoan.SEARCH_FOR_RETURN:{
				client.safeToClear = true;
				Return_Book next = (Return_Book)((SearchLoan)client.currentMain).returnPanel;
				ResultDisplay topaint = new ResultDisplay(client, received,next);
				client.RepaintMain(topaint);
			}
//			case SearchLoan.SEARCH_FOR_EXTEND:{
//				client.safeToClear = true;
//				Extend_Loan next = (Extend_Loan)((SearchLoan)client.currentMain).returnPanel;
//				ResultDisplay topaint = new ResultDisplay(client, received,next);
//				client.RepaintMain(topaint);
//			}
			}

			break;

		}
		
		
		
		case Message.SEARCH_MEMBER_RESPONSE:{
			
			int selector = (Integer)received.GetMessageData().get(2);
			switch(selector){
			case SearchMember.SEARCH:{
				client.safeToClear = true;
				
				ResultDisplay topaint = new ResultDisplay(client, received,null);
				client.RepaintMain(topaint);
				break;
			}
			
			case SearchMember.SEARCH_FOR_CREATE_LOAN:{}
			case SearchMember.SEARCH_FOR_CREATE_ORDER:{
				client.safeToClear = true;
				Book_opp next = (Book_opp)((SearchMember)client.currentMain).returnPanel;
				ResultDisplay topaint = new ResultDisplay(client, received,next);
				client.RepaintMain(topaint);

				break;
			}
			
			case SearchMember.SEARCH_FOR_SEARCH_LOAN:{
				client.safeToClear = true;
				SearchLoan next = (SearchLoan)((SearchMember)client.currentMain).returnPanel;
				ResultDisplay topaint = new ResultDisplay(client, received, next);
				client.RepaintMain(topaint);
				break;
			}
			case SearchMember.SEARCH_FOR_SEARCH_ORDER:{
				client.safeToClear = true;
				SearchOrder next = (SearchOrder)((SearchMember)client.currentMain).returnPanel;
				ResultDisplay topaint = new ResultDisplay(client, received, next);
				client.RepaintMain(topaint);
				break;
			}
			
			case SearchMember.SEARCH_FOR_RETURN_LOAN:{
				client.safeToClear = true;
				Return_Book next = (Return_Book)((SearchMember)client.currentMain).returnPanel;
				ResultDisplay topaint  = new ResultDisplay(client, received, next);
				client.RepaintMain(topaint);
				break;
			}
//			case SearchMember.SEARCH_FOR_EXTEND_LOAN:{
//				client.safeToClear = true;
//				Extend_Loan next = (Extend_Loan)((SearchMember)client.currentMain).returnPanel;
//				ResultDisplay topaint  = new ResultDisplay(client, received, next);
//				client.RepaintMain(topaint);
//				break;
//			}
			}			
			break;
		}//end of Message.SEARCH_MEMBER_RESPONSE
		
		case Message.CREATE_LOAN_RESPONSE:{}
		case Message.CREATE_ORDER_RESPONSE:{}
		case Message.CREATE_MEMBER_RESPONSE:{}
		case Message.ADD_BOOK_RESPONSE:{}
		case Message.UPDATE_BOOK_RESPONSE:{
			
			String res = (String)index.get(0);
			if (res.equals("OK")){				
				client.safeToClear = true;
				NotifyDialog notifier = new NotifyDialog(client,(String)data.get(0));
				Home home = new Home(client,client.client.publicMessages);
				client.RepaintMain(home);
				
			}else if (res.equals("ERROR")){
				String err = (String)data.get(0);
				NotifyDialog notifier = new NotifyDialog(client,err);
			}
			
			client.SetLoading(false);
			break;
		}
		
		case Message.DELETE_BOOK_RESPONSE:{
			String res = (String)data.get(0);
			if (res.equals("SUCCESS")){
				Home home = new Home(client,client.client.publicMessages);
				client.safeToClear = true;
				client.RepaintMain(home);
			}else{
				//TODO handle error
				System.out.print("DELETE BOOK ERROR");
			}
			
			NotifyDialog dlg = new NotifyDialog(client, res);
			break;
		}
		
		
		case Message.LATE_RETURN_REPORT_RESPONSE:{
			LateReturnReport topaint = new LateReturnReport(client, received);
			client.safeToClear = true;
			client.RepaintMain(topaint);
			break;
		}
		
		case Message.LOAN_REPORT_RESPONSE:{
			Loan_Report topaint = new Loan_Report(client,received);
			client.safeToClear = true;
			client.RepaintMain(topaint);
			break;
		}
		
		case Message.LATE_RETURN_REPORT_CATEGORY_RESPONSE:{}
		case Message.LATE_RETURN_REPORT_BOOK_RESPONSE:{
			String name = (String)received.GetMessageData().get(5);
			Late_report_result topaint = new Late_report_result(client, received,(LateReturnReport)client.currentMain,name);
			client.safeToClear = true;
			client.RepaintMain(topaint);
			break;
		}
		
		case Message.ACTIVITY_REPORT_RESPONSE:{
			
			//ResultDisplay topaint = ResultDisplay(client, received,null);
			//client.safeToClear = true;
			//client.RepaintMain(topaint);
			//break;
		}
		
		case Message.GET_MESSAGES_RESPONSE:{
			this.privateMessages = (ArrayList<SystemMesseges>)received.GetMessageData().get(0);
			this.client.GetMessages(privateMessages);
			break;
		}
		
		case Message.SEARCH_WORKER_RESPONSE:{
			client.safeToClear = true;
						
			ResultDisplay topaint = new ResultDisplay(client, received,null);
			client.RepaintMain(topaint);
			break;
		}
		
		case Message.EXTEND_LOAN_RESPONSE:{
			String res = (String)index.get(0);
			if (res.equals("OK")){				
				client.safeToClear = true;
				NotifyDialog notifier = new NotifyDialog(client,(String)data.get(0));
				Home home = new Home(client,client.client.publicMessages);
				client.RepaintMain(home);
				
			}else if (res.equals("ERROR")){
				String err = (String)data.get(0);
				NotifyDialog notifier = new NotifyDialog(client,err);
			}
			
			client.SetLoading(false);
			break;
		}
		
		case Message.CANCEL_ORDER_RESPONSE:{
			String res = (String)index.get(0);
			if (res.equals("OK")){				
				client.safeToClear = true;
				NotifyDialog notifier = new NotifyDialog(client,(String)data.get(0));
				Home home = new Home(client,client.client.publicMessages);
				client.RepaintMain(home);
				
			}else if (res.equals("ERROR")){
				String err = (String)data.get(0);
				NotifyDialog notifier = new NotifyDialog(client,err);
			}
			
			client.SetLoading(false);
			break;
		}

		
		case Message.PDF_RESPONSE:{
			pdfView vi = new pdfView(received);
		}
	
		
		
		
		}

	}
	
	
	/**
	 * Setter for UID
	 * @param uid - the user's ID
	 */
	public void SetUID(String uid){this.UID = uid;}
	
	/**
	 * Getter for UID
	 */
	public String GetUID(){return this.UID;}
	

}
